package com.invest.infra.excel.upload;

import com.invest.infra.excel.upload.vo.SheetErrorResult;
import com.invest.infra.excel.upload.vo.RowErrorResult;
import com.invest.infra.excel.utils.annotation.ExcelColumnAnnotationUtills;
import com.invest.infra.excel.wrapper.ExCell;
import com.invest.infra.excel.wrapper.ExSheet;
import com.invest.infra.excel.wrapper.ExWorkbook;
import com.invest.infra.excel.utils.annotation.ExcelColumnAnnotation;
import com.invest.infra.excel.utils.annotation.ExcelSheetAnnotation;
import com.invest.infra.mvc.utils.SpringContextUtils;
import com.invest.infra.excel.validator.CellValidator;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Collection;
import java.util.Map;

@Service
public class ExcelValidateService {

	@Autowired
	protected ApplicationContext ctx;

	/**
	 *
	 * @param esAnnotation
	 * @return
     */
	public SheetErrorResult validateSheet(ExWorkbook workbook, ExcelSheetAnnotation esAnnotation){

		ExSheet sheet = null;
		try {

			Assert.notEmpty(workbook.getSheets(),"模板错误，没有sheet");

			//校验sheet名称
			String firstSheet = workbook.getSheets().keySet().iterator().next();
			sheet = workbook.getSheets().get(firstSheet);
			if (StringUtils.isNotBlank(esAnnotation.name())) {
				sheet = workbook.getSheets().get(esAnnotation.name());
			}
			Assert.notNull(sheet,"sheet["+esAnnotation.name()+"]不存在");

			//校验最大行数
			Assert.isTrue(sheet.getRowCount() <= esAnnotation.maxRowCount(),"最大行数"+esAnnotation.maxRowCount());
			Assert.isTrue(sheet.getRowCount() > esAnnotation.dataStartRow() ,"文件没有数据");

			//校验标题
			if(!ArrayUtils.isEmpty(esAnnotation.titles())){
				ExCell[] cells = sheet.getCells(esAnnotation.titleIndex());
				for(int i =0;i<esAnnotation.titles().length;i++){
					Assert.isTrue(StringUtils.equals(esAnnotation.titles()[i],cells[i].getText()),
							"列["+esAnnotation.titles()[i] +"]不存在");
				}
			}
			return new SheetErrorResult(sheet==null?"":sheet.getName());

		}catch (IllegalArgumentException ex){
			SheetErrorResult result = new SheetErrorResult(sheet==null?"":sheet.getName());
			result.setErrorMessage(ex.getMessage());
			return result;
		}


	}

	public RowErrorResult validateRow(int row, ExCell[] cells, Collection<ExcelColumnAnnotation> exAnnotation, Map<String,Object> paramMap){

		RowErrorResult result = new RowErrorResult(row+1);

		//设定关键值
		for(int index =0; index <cells.length ;index++){
			ExcelColumnAnnotation annotation = ExcelColumnAnnotationUtills.getByIndex(exAnnotation,index);
			if(annotation != null && annotation.isKey()
					&& StringUtils.isNotBlank(cells[index].getText())){
				result.getKeyData().put(annotation.beanFieldName(),cells[index].getText());
			}
		}
		//此行没有主键数据【应该是空行 暂且忽略】
		if(MapUtils.isEmpty(result.getKeyData())){
			return result;
		}

		//校验
		for(int index =0; index <cells.length ;index++){
			ExcelColumnAnnotation annotation = ExcelColumnAnnotationUtills.getByIndex(exAnnotation,index);
			if(annotation == null){
				continue;
			}
			String[] validators = annotation.validators();
			for(String beanName : validators) {
				CellValidator bean = SpringContextUtils.getBean(ctx, beanName, CellValidator.class);
				String msg = bean.validate(paramMap, cells[index].getText());
				if(StringUtils.isNotBlank(msg)) {
					//加备注
					cells[index].addComment(row,msg);
					//返回错误信息
					result.getErrorMessages().add(annotation.columnTitle() +  msg);
					break;
				}
			}
		}
		return result;
	}
}
